#include "stdafx.h"
#include "ASN1UTCTime.h"

namespace AppliedCryptography
{
	ASN1UTCTime::ASN1UTCTime(ClassBits classBits, ConstructedBit constucted, TypeNumberBits number)
		: ASN1Encodable(classBits, constucted, number)
	{
	};

	ASN1UTCTime::ASN1UTCTime()
		: ASN1Encodable(Universal, Primitive, UTCTime)
	{
	};

	ASN1UTCTime::ASN1UTCTime(const std::string& time)
		: ASN1Encodable(Universal, Primitive, UTCTime)
	{
		this->set(time);
	};

	ASN1UTCTime& ASN1UTCTime::set(const std::string& time)
	{
		// Format: YYYY-MM-DD hh:mm:ss
		tm t;

		sscanf_s(time.c_str(), "%4d-%2d-%2d %2d:%2d:%2d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec);

		t.tm_year -= 1900;
		t.tm_mon -= 1;

		_datetime = _mkgmtime(&t);

		if(gmtime_s(&t, &_datetime) != 0)
			t.tm_year -= 1900;;

		return *this;
	};

	tm ASN1UTCTime::get() const
	{
		return this->convertTime(_datetime);
	};

	std::string ASN1UTCTime::getString(std::string& format) const
	{
		char buffer [1024*4];
		tm t = convertTime(_datetime);

		strftime(buffer, 1024*4, format.c_str(), &t);
		return std::string(buffer);
	};

	std::vector<byte> ASN1UTCTime::getContentBits() const
	{
		std::vector<byte> buffer;
		std::string str;
		tm t = convertTime(_datetime);

		// Year
		buffer.push_back(0x30 + (t.tm_year % 100) / 10);
		buffer.push_back(0x30 + (t.tm_year % 100) % 10);

		// month
		buffer.push_back(0x30 + t.tm_mon / 10);
		buffer.push_back(0x31 + t.tm_mon % 10);

		// month day
		buffer.push_back(0x30 + t.tm_mday / 10);
		buffer.push_back(0x30 + t.tm_mday % 10);

		// hour
		buffer.push_back(0x30 + t.tm_hour / 10);
		buffer.push_back(0x30 + t.tm_hour % 10);

		// min
		buffer.push_back(0x30 + t.tm_min / 10);
		buffer.push_back(0x30 + t.tm_min % 10);

		// sec 
		buffer.push_back(0x30 + t.tm_sec / 10);
		buffer.push_back(0x30 + t.tm_sec % 10);

		buffer.push_back('Z');

		return buffer;
	};

	tm ASN1UTCTime::convertTime(const time_t &time) const
	{
		tm t;

		if(gmtime_s(&t, &_datetime) != 0)
		{
			throw std::exception("Cannot format time");
		};

		return t;
	};

}; // namespace AppliedCryptography
